#!/usr/bin/env python
# -*- coding: utf-8 -*-
#=======================================#
# @author: RedSoxFan and NerfSoldier
# @copyright: 2012 RedSoxFan and NerfSoldier
# @license: GNU General Public License v3.0 
#           <http://www.gnu.org/copyleft/gpl.html>
# @summary: Text/Code Editor
#=======================================#

#=======================================#
# Imports
#=======================================#
# Python
import os
from PyQt4 import QtGui, QtCore
from parsers import CodeCompletionPopup
# DarkDev
#=======================================#

class Editor(QtGui.QTextEdit):
    def __init__(self,project,parser,fname):
        super(Editor,self).__init__()
        
        # Initialize Editor
        self.project = project
        self.darkdev = project.darkdev
        self.workspace = project.workspace
        self.setLineWrapMode(0)
        self.setFrameStyle(0)
        self.setAutoFillBackground(True)
        self.ln = QtGui.QTextEdit(self)
        self.parser = parser(self.project,self,fname)
        
        # Line Numbers Configuration
        self.ln.setFrameStyle(0)
        self.ln.move(0,20)
        self.ln.setReadOnly(True)
        self.ln.setFocusPolicy(0)
        self.ln.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.ln.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        for k in ["Default",self.parser.key]:
            if "%s.Editor.ShowLineNumbers"%k in self.workspace.window.ddcg:
                self.showLineNumbers = self.workspace.window.ddcg["%s.Editor.ShowLineNumbers"%k]
                if self.showLineNumbers: 
                    self.setViewportMargins(20,20,0,0)
                    self.ln.show()
                else: 
                    self.setViewportMargins(0,20,0,0)
                    self.ln.hide()
                    
        # Create Toolbar
        self.toolbar = QtGui.QToolBar(self)
        self.toolbar.setStyleSheet("background:#3c3c3c")
        self.toolbar.setIconSize(QtCore.QSize(16,16))
        
        # Group 1 - File I/O
        # Save
        self.toolbar_save = QtGui.QAction(QtGui.QIcon("resources/toolbar/save.png"),"Save",self)
        self.toolbar_save.setToolTip("Save\nCtrl+S")        
        self.toolbar_save.setShortcut('Ctrl+S')
        self.toolbar_save.triggered.connect(self.parser.save)
        self.toolbar.addAction(self.toolbar_save)
        # Save As
        self.toolbar_saveas = QtGui.QAction(QtGui.QIcon("resources/toolbar/saveas.png"),"Save As",self)        
        self.toolbar_saveas.setShortcut('Ctrl+Shift+S')
        self.toolbar_saveas.setToolTip("Save As\nCtrl+Shift+S")
        self.toolbar_saveas.triggered.connect(self.parser.saveas)
        self.toolbar.addAction(self.toolbar_saveas)
        # Revert
        self.toolbar_revert = QtGui.QAction(QtGui.QIcon("resources/toolbar/revert.png"),"Revert",self)        
        self.toolbar_revert.setShortcut('Ctrl+Shift+R')
        self.toolbar_revert.setToolTip("Revert\nCtrl+Shift+R")
        self.toolbar_revert.triggered.connect(self.parser.revert)
        self.toolbar.addAction(self.toolbar_revert)
        
        self.toolbar.addSeparator()
        
        # Group 2 - Clipboard
        # Cut
        self.toolbar_cut = QtGui.QAction(QtGui.QIcon("resources/toolbar/cut.png"),"Cut",self)
        self.toolbar_cut.setToolTip("Cut\nCtrl+X")
        self.toolbar_cut.triggered.connect(self.cut)
        self.toolbar.addAction(self.toolbar_cut)
        # Copy
        self.toolbar_copy = QtGui.QAction(QtGui.QIcon("resources/toolbar/copy.png"),"Copy",self)
        self.toolbar_copy.setToolTip("Copy\nCtrl+C")
        self.toolbar_copy.triggered.connect(self.copy)
        self.toolbar.addAction(self.toolbar_copy)
        # Paste
        self.toolbar_paste = QtGui.QAction(QtGui.QIcon("resources/toolbar/paste.png"),"Paste",self)
        self.toolbar_paste.triggered.connect(self.paste)
        self.toolbar_paste.setToolTip("Paste\nCtrl+V")
        self.toolbar.addAction(self.toolbar_paste)
        
        # Connect To Signals To Modify LineNumbers and Highlight Of Current Line
        self.cursorPositionChanged.connect(self.update)
        self.verticalScrollBar().sliderMoved.connect(self.update)
        self.verticalScrollBar().valueChanged.connect(self.update)
        self.document().contentsChanged.connect(self.update_modified)
        
        self.update()
    
    def keyPressEvent(self,e):
        '''
        Override to allow for CodeCompletionPopup to handle keyPressEvents (when visible)
        '''
        if self.parser.qc and self.parser.qc.isVisible():
            if e.key() in [QtCore.Qt.Key_Enter,QtCore.Qt.Key_Return,QtCore.Qt.Key_Escape,QtCore.Qt.Key_Up,QtCore.Qt.Key_Down]:
                self.parser.qc.setFocus()
                e.ignore()
                return
            self.parser.qc.hide()
        elif self.parser.qc and CodeCompletionPopup.ignoreNewLine and e.key() in [QtCore.Qt.Key_Return,QtCore.Qt.Key_Enter]:
            CodeCompletionPopup.ignoreNewLine = False
            e.ignore()
            return
        self.parser.frame.hide()
        return QtGui.QTextEdit.keyPressEvent(self,e)
    
    def mousePressEvent(self,e):
        self.parser.frame.hide()
        if self.parser.qc: self.parser.qc.hide()
        return QtGui.QTextEdit.mousePressEvent(self,e)
    
    def mouseReleaseEvent(self,e):
        self.parser.frame.hide()
        if self.parser.qc: self.parser.qc.hide()
        return QtGui.QTextEdit.mouseReleaseEvent(self,e)
    
    def update(self,*args,**kwargs):
        if self.showLineNumbers:
            # Resize Viewport Based On Text Width and Synchronize Scrollbars
            v = self.verticalScrollBar().sliderPosition()
            l = self.document().lineCount()
            self.ln.setMaximumWidth(self.ln.fontMetrics().width("M"*len("%s"%l))+10)
            self.ln.setMinimumWidth(self.ln.maximumWidth())
            self.ln.move(0,self.toolbar.height())
            self.ln.resize(self.ln.maximumWidth(),self.height()-self.toolbar.height())
            self.setViewportMargins(self.ln.maximumWidth(),self.toolbar.height(),0,0)
            self.cur_line = self.textCursor().block().blockNumber()
            txt = ""
            for x in range(l):
                if x!=self.cur_line: txt+="%s<br>"%(x+1)
                else: txt+="<b>%s</b><br>"%(x+1) 
            txt = "<html><body align=\"right\">%s<body></html>"%txt[:-1]
            self.ln.setHtml(txt)
            self.ln.verticalScrollBar().setSliderPosition(v)
        # Highlight Current Line
        self.hiliteln = QtGui.QTextEdit.ExtraSelection()
        self.hiliteln.cursor = self.textCursor()
        self.hiliteln.format.setProperty(QtGui.QTextFormat.FullWidthSelection,True)
        self.hiliteln.format.setBackground(QtGui.QBrush(QtGui.QColor("#333")))
        self.setExtraSelections([self.hiliteln])

    def set_tab_text(self,text):
        self.workspace.window.tabs.setTabText(self.workspace.window.tabs.indexOf(self),text)
    
    def update_modified(self,*a,**k):
        self.set_tab_text("*%s"%os.path.basename(self.parser.fname))
        self.update()
        
    def resizeEvent(self,e):
        self.toolbar.resize(self.width(),self.toolbar.height())